﻿using System;
using System.Collections.Generic;
using Xin478.MySocket;

namespace Xin478.CSWork.Common
{
    public class DatagramWorker : IDatagramAnalyze
    {
        static readonly byte[] BeginTag = System.Text.Encoding.UTF8.GetBytes("B_TAG");
     
        public IList<byte[]> Disassemble(Session session,byte[] dataBytes,int recv)
        {
            IList<byte[]> list = new List<byte[]>();
            
            byte[] temp;
            if (session.Datagram != null)
            {
                temp = new byte[session.Datagram.Length + recv];
                Array.Copy(session.Datagram, temp, session.Datagram.Length);
                Array.Copy(dataBytes, 0, temp, session.Datagram.Length, recv);
                session.Datagram = null;
            }
            else if (recv != dataBytes.Length)
            {
                temp = new byte[recv];
                Array.Copy(dataBytes, temp, recv);
            }
            else
                temp = dataBytes;

            int i = 0, j = 0;

            for (; i < temp.Length; i++)
            {
                if (temp[i] == BeginTag[j])
                {
                    if (++j == BeginTag.Length)
                    {
                        ++i;  //移动到长度标示部分的第一位上
                        if (i + 4 >= temp.Length)
                        {
                            session.Datagram = new byte[temp.Length - i  + BeginTag.Length];
                            Array.Copy(temp, i - BeginTag.Length, session.Datagram, 0, session.Datagram.Length);
                            break;
                        }

                        int len = ((temp[i] & 0x000000ff) << 24) | ((temp[i + 1] & 0x000000ff) << 16) | ((temp[i + 2] & 0x000000ff) << 8) | (temp[i + 3] & 0x000000ff);

                        i += 4;//移动数据部分的第一位上

                        if (i + len <= temp.Length)
                        {
                            byte[] item = new byte[len];
                            
                            Array.Copy(temp, i, item, 0, len);
                            list.Add(item);
                            i += len-1; //移动到理论上下一个开始符的前一位上
                            j = 0;
                        }
                        else
                        {
                            session.Datagram = new byte[temp.Length - i + 4 + BeginTag.Length];
                            Array.Copy(temp, i - 4 - BeginTag.Length, session.Datagram, 0, session.Datagram.Length);
                            break;
                        }
                    }
                }
                else if (j != 0) j = 0;
            }

            if (list.Count == 0 && session.Datagram == null)
            {
                session.Datagram = temp;
            }

            if (session.Datagram != null && session.Datagram.Length > Session.MAXDATAGRAMSIZE) session.Datagram = null;

           // Array.Clear(dataBytes, 0, dataBytes.Length);

            return list;
        }

        public byte[] Assemble(byte[] dataBytes)
        {
            byte[] datas = new byte[dataBytes.Length + 4 + BeginTag.Length ];
            Array.Copy(BeginTag, datas, BeginTag.Length);

            datas[BeginTag.Length] = (byte)((dataBytes.Length >> 24) & 0xFF);
            datas[BeginTag.Length + 1] = (byte)((dataBytes.Length >> 16) & 0xFF);
            datas[BeginTag.Length + 2] = (byte)((dataBytes.Length >> 8) & 0xFF);
            datas[BeginTag.Length + 3] = (byte)(dataBytes.Length & 0xFF);

            Array.Copy(dataBytes, 0, datas, BeginTag.Length + 4, dataBytes.Length);

            return datas;
        }
    }
}
